﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Linq.Expressions;
using System.Text;

namespace PubSubGeneric
{
    public class SubscriptionInfo<T> : ISubscriptionInfo<T>
    {
        Func<T, bool> _compiledpredicate;
        Expression<Func<T, bool>> _predicate;

        public SubscriptionInfo(ISubscriber<T> subscriber)
            : this(subscriber, null)
        {
        }

        public SubscriptionInfo(ISubscriber<T> subscriber, Expression<Func<T, bool>> Predicate)
        {
            this.Subscriber = subscriber;
            this.Predicate = Predicate;
        }

        public override int GetHashCode()
        {
            return typeof(T).GetHashCode() ^ this.Subscriber.GetHashCode() ^ (this.Predicate == null ?  0: this.Predicate.Body.ToString().GetHashCode());
        }

        public override bool Equals(object obj)
        {
            ISubscriptionInfo<T> other = obj as ISubscriptionInfo<T>;
            if (other != null)
                if (this.Subscriber.Equals(other.Subscriber))
                    if (Equals((this.Predicate == null ? "" : this.Predicate.Body.ToString()), (other.Predicate == null ? "" : other.Predicate.Body.ToString())))
                        return true;
            return false;
        }

        public ISubscriber<T> Subscriber { get; set; }

        public Expression<Func<T, bool>> Predicate
        {
            get
            {
                return _predicate;
            }
            set
            {
                _predicate = value;
                if (_predicate != null)
                    _compiledpredicate = _predicate.Compile();
            }
        }

        public Func<T, bool> CompiledPredicate
        {
            get
            {
                if (_compiledpredicate == null && this.Predicate != null)
                    _compiledpredicate = this.Predicate.Compile();
                return _compiledpredicate;
            }
            private set
            {
                _compiledpredicate = value;
            }
        }

    }
}
